/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.wonders.xianningsocialinsurance.utils;

/**
 */
public abstract class StringUtils {

	private static final String FOLDER_SEPARATOR = "/";

	private static final String WINDOWS_FOLDER_SEPARATOR = "\\";

	private static final String TOP_PATH = "..";

	private static final String CURRENT_PATH = ".";

	private static final char EXTENSION_SEPARATOR = '.';

	// ---------------------------------------------------------------------
	// General convenience methods for working with Strings
	// ---------------------------------------------------------------------

	// 判断str是否为空值
	public static boolean hasLength(CharSequence str) {
		return (str != null && str.length() > 0);
	}

	/**
	 * 判断字符串是否有长度 注意CharSequence是String类的上层接口
	 * 
	 * @param str
	 * @return
	 */
	public static boolean hasLength(String str) {
		return hasLength((CharSequence) str);
	}

	/**
	 * 判断CharSequence是否有实际内容，空格不算
	 * <p>
	 * 
	 * <pre>
	 * StringUtils.hasText(null) = false
	 * StringUtils.hasText("") = false
	 * StringUtils.hasText(" ") = false
	 * StringUtils.hasText("12345") = true
	 * StringUtils.hasText(" 12345 ") = true
	 */
	public static boolean hasText(CharSequence str) {
		// 如果str为空，返回false
		if (!hasLength(str)) {
			return false;
		}
		// 获取str的长度
		int strLen = str.length();
		// 循环遍历str
		for (int i = 0; i < strLen; i++) {
			// 如果在0到strlen之间，有一个不是空格，说明有内容，返回true
			if (!Character.isWhitespace(str.charAt(i))) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 判断str是否是实际内容，纯空格组成的str返回false
	 */
	public static boolean hasText(String str) {
		return hasText((CharSequence) str);
	}

	/**
	 * 检测CharSequence是否有空白字符
	 */
	public static boolean containsWhitespace(CharSequence str) {
		// 如果长度为0，则返回false
		if (!hasLength(str)) {
			return false;
		}
		int strLen = str.length();
		// 循环遍历str
		for (int i = 0; i < strLen; i++) {
			// 如果在0到strLen之间有空白符，则返回true
			if (Character.isWhitespace(str.charAt(i))) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 判断给定的字符串str是否含有空白符
	 */
	public static boolean containsWhitespace(String str) {
		return containsWhitespace((CharSequence) str);
	}

	/**
	 * 去掉str开头和结尾的空白符
	 */
	public static String trimWhitespace(String str) {
		// 如果没有长度，则放回str
		if (!hasLength(str)) {
			return str;
		}

		StringBuilder sb = new StringBuilder(str);
		// 如果sb.charAt(0)是空白符的话，删除该空白符
		while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
			sb.deleteCharAt(0);
		}
		// 如果末尾是空白符的话，也删除该空白符
		while (sb.length() > 0
				&& Character.isWhitespace(sb.charAt(sb.length() - 1))) {
			sb.deleteCharAt(sb.length() - 1);
		}
		// 返回去掉开头结尾空白符之后的字符串
		return sb.toString();
	}

	/**
	 * 删除给定的字符串中所有的空白符
	 */
	public static String trimAllWhitespace(String str) {
		// 如果str没有长度，返回str
		if (!hasLength(str)) {
			return str;
		}
		StringBuilder sb = new StringBuilder(str);
		int index = 0;
		// 循环遍历sb
		while (sb.length() > index) {
			// 如果当前位置index为空白符，则删除之
			if (Character.isWhitespace(sb.charAt(index))) {
				sb.deleteCharAt(index);
			} else {
				index++;
			}
		}
		// 返回去掉空白符之后的字符串
		return sb.toString();
	}

	/**
	 * 删除掉str的开头的空白符，如果有的话
	 */
	public static String trimLeadingWhitespace(String str) {
		// 如果str的长度为0，返回str
		if (!hasLength(str)) {
			return str;
		}
		StringBuilder sb = new StringBuilder(str);
		// 如果开头有字符串，则删除之
		while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
			sb.deleteCharAt(0);
		}
		// 返回删除开头空白符的字符串
		return sb.toString();
	}

	/**
	 * 删除str结尾的空白符，如果结尾是空白符的话
	 */
	public static String trimTrailingWhitespace(String str) {
		// 如果str的长度为0，返回str
		if (!hasLength(str)) {
			return str;
		}
		StringBuilder sb = new StringBuilder(str);
		// 如结尾头有字符串，则删除之
		while (sb.length() > 0
				&& Character.isWhitespace(sb.charAt(sb.length() - 1))) {
			sb.deleteCharAt(sb.length() - 1);
		}
		// 返回删除开头空白符的字符串
		return sb.toString();
	}

	/**
	 * 删除str中开头是字符是给定字符的那个字符
	 */
	public static String trimLeadingCharacter(String str, char leadingCharacter) {
		// 如果str的长度为0，返回str
		if (!hasLength(str)) {
			return str;
		}
		StringBuilder sb = new StringBuilder(str);
		// 判断sb的开头是否==leadingCharacter,若是就删除，否则什么也不做
		while (sb.length() > 0 && sb.charAt(0) == leadingCharacter) {
			sb.deleteCharAt(0);
		}
		return sb.toString();
	}

	/**
	 * 删除结尾等于trailingCharacter的那个字符
	 */
	public static String trimTrailingCharacter(String str,
			char trailingCharacter) {
		// 如果str的长度为0，返回str
		if (!hasLength(str)) {
			return str;
		}
		StringBuilder sb = new StringBuilder(str);
		// 判断sb的开头是否==leadingCharacter,若是就删除，否则什么也不做
		while (sb.length() > 0
				&& sb.charAt(sb.length() - 1) == trailingCharacter) {
			sb.deleteCharAt(sb.length() - 1);
		}
		return sb.toString();
	}

	/**
	 * 检测str的前缀是否是prefix，大小写不敏感
	 */
	public static boolean startsWithIgnoreCase(String str, String prefix) {
		if (str == null || prefix == null) {
			return false;
		}
		// 如果是则返回true
		if (str.startsWith(prefix)) {
			return true;
		}
		// 如果str小于前缀，则返回false
		if (str.length() < prefix.length()) {
			return false;
		}
		// 设定大小写不明感
		// 把str的前面长度等于prefix的字符变小写
		String lcStr = str.substring(0, prefix.length()).toLowerCase();
		// 把prefix变小写
		String lcPrefix = prefix.toLowerCase();
		// 判断
		return lcStr.equals(lcPrefix);
	}

	/**
	 * 检测str的后缀是否是prefix，大小写不敏感
	 */
	public static boolean endsWithIgnoreCase(String str, String suffix) {
		if (str == null || suffix == null) {
			return false;
		}
		// 如果后缀是suffix，返回true
		if (str.endsWith(suffix)) {
			return true;
		}
		if (str.length() < suffix.length()) {
			return false;
		}
		// 设定大小写不敏感
		String lcStr = str.substring(str.length() - suffix.length())
				.toLowerCase();
		String lcSuffix = suffix.toLowerCase();
		return lcStr.equals(lcSuffix);
	}

	/**
	 * 判断给定的str中是否有在位置index处存在子序列subString
	 */
	public static boolean substringMatch(CharSequence str, int index,
			CharSequence substring) {
		for (int j = 0; j < substring.length(); j++) {
			int i = index + j;
			// 如果i>=str.length说明str字符串自index到最后的长度小于subString
			// str.charAt(i) != substring.charAt(j),如果当前j位置字符和str中i位置字符不相等
			if (i >= str.length() || str.charAt(i) != substring.charAt(j)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 检测str中出现sub子字符串的个数.
	 */
	public static int countOccurrencesOf(String str, String sub) {
		// 边界处理
		if (str == null || sub == null || str.length() == 0
				|| sub.length() == 0) {
			return 0;
		}
		// 计数器
		int count = 0;
		// 记录当前位置
		int pos = 0;
		int idx;
		// indexOf(String str,int fromIndex)str - 要搜索的子字符串。
		// fromIndex - 开始搜索的索引位置
		// 如果含有此sub，则计数器+1
		while ((idx = str.indexOf(sub, pos)) != -1) {
			++count;
			// 下一个开始比较的位置
			pos = idx + sub.length();
		}
		// 返回sub出现的个数
		return count;
	}

	/**
	 * 用newPattern来替换inString中的oldPattern
	 */
	public static String replace(String inString, String oldPattern,
			String newPattern) {
		// 边界处理
		if (!hasLength(inString) || !hasLength(oldPattern)
				|| newPattern == null) {
			return inString;
		}

		StringBuilder sb = new StringBuilder();
		int pos = 0;
		// 返回oldPattern在inString的位置索引
		int index = inString.indexOf(oldPattern);
		// 记录oldPattern的长度
		int patLen = oldPattern.length();
		while (index >= 0) {
			// 保存index之前的inString子串
			sb.append(inString.substring(pos, index));
			// 拼接新的字符（串）
			sb.append(newPattern);
			pos = index + patLen;
			// 检测pos之后是否还有oldPattern,如果有继续替换
			index = inString.indexOf(oldPattern, pos);
		}
		// 拼接pos之后的字符串
		sb.append(inString.substring(pos));
		// remember to append any characters to the right of a match
		return sb.toString();
	}

	/**
	 * 删除inString中符合pattern要求的字符（串） 实现方法是：把inString中符合pattern的字符（串）替换成“”从而实现删除
	 */
	public static String delete(String inString, String pattern) {
		return replace(inString, pattern, "");
	}

	/**
	 * 到此可以发先StringBuilder的强大作用 删除inString中在charsToDelete中存在的字符 例如 inString =
	 * "abddfkjfd"; charsToDelete = "cdjf"; 则处理后的inString = "abk"
	 */
	public static String deleteAny(String inString, String charsToDelete) {
		// 边界处理
		if (!hasLength(inString) || !hasLength(charsToDelete)) {
			return inString;
		}
		// 字符构造器
		StringBuilder sb = new StringBuilder();
		// 循环遍历inString,判断每个字符是否在charsToDelete中
		for (int i = 0; i < inString.length(); i++) {
			// 获取当前位置i的字符c
			char c = inString.charAt(i);
			// 如果charsToDelete中不包含c，则拼接到sb中
			if (charsToDelete.indexOf(c) == -1) {
				sb.append(c);
			}
		}
		// 返回处理过的字符串
		return sb.toString();
	}

	// ---------------------------------------------------------------------
	// Convenience methods for working with formatted Strings
	// ---------------------------------------------------------------------

	/**
	 * 用单引号把非空的str括起来，例如str == "hello" 那么返回的将是‘hello’
	 */
	public static String quote(String str) {
		return (str != null ? "'" + str + "'" : null);
	}

	/**
	 * 如果给定的对象是String类型，则调用quote方法处理，否则什么都不做原样返回
	 */
	public static Object quoteIfString(Object obj) {
		return (obj instanceof String ? quote((String) obj) : obj);
	}

	/**
	 * Unqualify a string qualified by a '.' dot character. For example,
	 * "this.name.is.qualified", returns "qualified".
	 * 
	 * @param qualifiedName
	 *            the qualified name
	 */
	public static String unqualify(String qualifiedName) {
		return unqualify(qualifiedName, '.');
	}

	/**
	 * 获取给定的字符串中，最后一个满足分隔符separator之后字符串， 例如 qualifiedName =
	 * "this:name:is:qualified" separator = ':' 那么处理过后的字符串就是 qualified
	 */
	public static String unqualify(String qualifiedName, char separator) {
		return qualifiedName
				.substring(qualifiedName.lastIndexOf(separator) + 1);
	}

	/**
	 * 设置首字母为大写
	 */
	public static String capitalize(String str) {
		return changeFirstCharacterCase(str, true);
	}

	/**
	 * 设置str首字母为小写
	 */
	public static String uncapitalize(String str) {
		return changeFirstCharacterCase(str, false);
	}

	private static String changeFirstCharacterCase(String str,
			boolean capitalize) {
		if (str == null || str.length() == 0) {
			return str;
		}
		StringBuilder sb = new StringBuilder(str.length());
		if (capitalize) {// 如果首字母要求大写的话
			sb.append(Character.toUpperCase(str.charAt(0)));
		} else { // 否则首字母设置为小写
			sb.append(Character.toLowerCase(str.charAt(0)));
		}
		// 拼接首字母剩下的字符串
		sb.append(str.substring(1));
		return sb.toString();
	}

	/**
	 * 获得给用路径path中的文件名 例如 "mypath/myfile.txt" -> "myfile.txt".
	 */
	public static String getFilename(String path) {
		// 边界处理
		if (path == null) {
			return null;
		}
		// 获得path中最后一个文件分隔符‘/’的位置
		int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR);
		// 如果没有分隔符，说明给定的就是文件名，直接返回即可，否则返回分隔符剩下的字符
		return (separatorIndex != -1 ? path.substring(separatorIndex + 1)
				: path);
	}

	/**
	 * 获得文件名的扩展名，也就是格式 e.g. "mypath/myfile.txt" -> "txt".
	 */
	public static String getFilenameExtension(String path) {
		// 边界处理
		if (path == null) {
			return null;
		}
		// 获得最后一个‘.’的位置
		int extIndex = path.lastIndexOf(EXTENSION_SEPARATOR);
		if (extIndex == -1) {
			return null;
		}
		// 找到最后一个文件分隔符‘/’的位置
		int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR);
		// 如果folderIndex在extIndex的右边，返回null
		if (folderIndex > extIndex) {
			return null;
		}
		// 返回‘.’之后的子字符串
		return path.substring(extIndex + 1);
	}

	/**
	 * 过滤掉文件的扩展名 例如. "mypath/myfile.txt" -> "mypath/myfile".
	 */
	public static String stripFilenameExtension(String path) {
		// 边界处理
		if (path == null) {
			return null;
		}
		// 获得最后一个‘.’的位置
		int extIndex = path.lastIndexOf(EXTENSION_SEPARATOR);
		if (extIndex == -1) {
			return path;
		}
		// 找到最后一个文件分隔符‘/’的位置
		int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR);
		// 如果folderIndex在extIndex的右边，path是文件路径，没有扩展名可言，直接原样返回
		if (folderIndex > extIndex) {
			return path;
		}
		// 返回滤掉扩展名之后的子字符串
		return path.substring(0, extIndex);
	}

	/**
	 * 该方法的作用如下 如果path = "/hello/world/ relativePtah = "java" 经过处理后返回
	 * /hello/world/java 如果path = "helloworld" 那么处理后返回java 这个方法少了空值判断，个人觉得加上严谨些
	 */
	public static String applyRelativePath(String path, String relativePath) {
		// 找到最后个文件分隔符的位置
		int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR);
		if (separatorIndex != -1) {// 如果有文件分隔符
			// 获得从0到最后一个分隔符之前的子字符串
			String newPath = path.substring(0, separatorIndex);
			// 如果relativePath不是以文件分隔符开头
			if (!relativePath.startsWith(FOLDER_SEPARATOR)) {
				// 把newPath后面追加一个/
				newPath += FOLDER_SEPARATOR;
			}
			// 返回newPath+relativePath
			return newPath + relativePath;
		} else {// 如果没有，就返回relativePath
			return relativePath;
		}
	}// end

	/**
	 * Normalize the path by suppressing sequences like "path/.." and inner
	 * simple dots.
	 * <p>
	 * The result is convenient for path comparison. For other uses, notice that
	 * Windows separators ("\") are replaced by simple slashes.
	 * 
	 * @param path
	 *            the original path
	 * @return the normalized path
	 */

	/**
	 * Compare two paths after normalization of them.
	 * 
	 * @param path1
	 *            first path for comparison
	 * @param path2
	 *            second path for comparison
	 * @return whether the two paths are equivalent after normalization
	 */

	// 检测是否是有效路径locale的语法是locale -O 64 -a | -m | -c -k Name ...
	private static void validateLocalePart(String localePart) {
		for (int i = 0; i < localePart.length(); i++) {
			char ch = localePart.charAt(i);
			// 检测当前字符
			if (ch != '_' && ch != ' ' && !Character.isLetterOrDigit(ch)) {
				throw new IllegalArgumentException("Locale part \""
						+ localePart + "\" contains invalid characters");
			}
		}
	}

	public static boolean isEmpty(CharSequence cs) {
		return cs == null || cs.length() == 0;
	}
	public static boolean toBool(String cs) {
		return Boolean.getBoolean(cs);
	}
	
}
